package com.autonavi.yunda.yunji.service;

import com.alibaba.buc.sso.client.vo.BucSSOUser;
import com.autonavi.yunda.yunji.common.exception.AmapException;
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode;
import com.autonavi.yunda.yunji.common.exception.AmapPreconditions;
import com.autonavi.yunda.yunji.core.config.ApplicationEnvConfig;
import com.autonavi.yunda.yunji.core.enums.OperationRecordType;
import com.autonavi.yunda.yunji.core.enums.RoleType;
import com.autonavi.yunda.yunji.core.enums.UserPermission;
import com.autonavi.yunda.yunji.core.model.condition.UserQueryCondition;
import com.autonavi.yunda.yunji.core.model.dto.UserDTO;
import com.autonavi.yunda.yunji.core.model.mappers.UserMapper;
import com.autonavi.yunda.yunji.core.vo.response.UserPageVO;
import com.autonavi.yunda.yunji.groovy.AdminGroovyUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author cizhong.wcs
 * @date 2023/9/4 14:18
 */
@Slf4j
@Component
public class UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserProjectService userProjectService;
    @Resource
    private ApplicationEnvConfig applicationEnvConfig;
    @Resource
    private OperationRecordService operationRecordService;
    @Resource
    private FactoryUserService factoryUserService;

    public RoleType getAndInitUserRole(BucSSOUser user) {
        return checkAndInit(user).getUserRole();
    }

    public RoleType getUserRole(String userId) {
        UserDTO userDTO = fetchUserByUserId(userId);
        return userDTO == null ? RoleType.NORMAL : userDTO.getUserRole();
    }

    public UserDTO fetchUserByUserId(String userId) {
        LambdaQueryWrapper<UserDTO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserDTO::getUserId, userId);
        return userMapper.selectOne(wrapper);
    }

    public UserDTO fetchUserByUserIdOrThrow(String userId) {
        UserDTO userDTO = fetchUserByUserId(userId);
        if (userDTO == null) {
            throw new AmapException(AmapExceptionCode.COMMON_ILLEGAL_PARAM, "用户不存在");
        }
        return userDTO;
    }

    public UserPageVO listPage(UserQueryCondition condition) {
        Page<UserDTO> page = new Page<>(condition.getPageNo(), condition.getPageSize());
        LambdaQueryWrapper<UserDTO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(condition.getUserId()), UserDTO::getUserId, condition.getUserId());
        queryWrapper.like(StringUtils.isNotBlank(condition.getLastName()), UserDTO::getLastName, condition.getLastName());
        queryWrapper.like(StringUtils.isNotBlank(condition.getNickName()), UserDTO::getNickName, condition.getNickName());
        queryWrapper.eq(condition.getUserRole() != null, UserDTO::getUserRole, condition.getUserRole());
        queryWrapper.orderByDesc(UserDTO::getId);
        page = userMapper.selectPage(page, queryWrapper);
        List<UserDTO> records = page.getRecords();

        Map<String, List<String>> userProjectIdsMap = userProjectService.fetchUserProjectIdsMap(
                records.stream().map(UserDTO::getUserId).collect(Collectors.toList()),
                factoryUserService.getCurrentUserBdId()
        );
        records.forEach(record ->
                record.setProjectIds(userProjectIdsMap.getOrDefault(record.getUserId(), List.of()))
        );

        return new UserPageVO(records, page.getTotal());
    }

    public List<UserDTO> listUserByPermission(UserPermission permission) {
        AmapPreconditions.checkNotNull(permission);
        LambdaQueryWrapper<UserDTO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(UserDTO::getPermissions, permission);
        return userMapper.selectList(queryWrapper);
    }

    private UserDTO checkAndInit(BucSSOUser user) {
        UserDTO userDTO = fetchUserByUserId(user.getEmpId());
        if (userDTO == null) {
            userDTO = new UserDTO();
            userDTO.setUserId(user.getEmpId());
            userDTO.setUserRole(RoleType.NORMAL);
            userDTO.setLastName(user.getLastName());
            userDTO.setNickName(user.getNickNameCn());
            userMapper.insert(userDTO);
            operationRecordService.add(OperationRecordType.UserSubType.CREATE, user.getEmpId());
            initUserProject(user.getEmpId());
        }
        return userDTO;
    }

    public void addUser(String userId) {
        UserDTO userDTO = fetchUserByUserId(userId);
        AmapPreconditions.checkArgumentForUser(userDTO == null, "用户已存在");
        Map<String, String> user = AdminGroovyUtil.searchUser(factoryUserService.transferToFactoryEmployeeId(userId));
        AmapPreconditions.checkArgumentForUser(user != null, "用户查找失败:" + userId);
        userDTO = new UserDTO();
        userDTO.setUserId(userId);
        userDTO.setLastName(user.get("name"));
        userDTO.setNickName(user.get("nickName"));
        userDTO.setUserRole(RoleType.NORMAL);
        userMapper.insert(userDTO);
    }

    private void initUserProject(String userId) {
        if (applicationEnvConfig.isPrepub() || applicationEnvConfig.isPublish()) {
            return;
        }
        //初始化测试项目和经典案例
        List<String> initProjectIdList = List.of("2ea8053f3df841ce99300a3308643145", "0a29d5ca8a804bbe975b0ad01560e8f2");
        userProjectService.updateUserProjectIds(userId, initProjectIdList, userId);
    }

    public void updateUser(UserDTO dto) {
        userMapper.update(dto, new UpdateWrapper<UserDTO>().eq("user_id", dto.getUserId()));
    }
}
